package com.xbongbong.paas.enums;

import com.xbongbong.pro.statistic.constant.RelatedProductConstant;
import com.xbongbong.saas.enums.product.AssembleInProductEnum;
import com.xbongbong.saas.enums.product.AssembleProductEnum;
import com.xbongbong.saas.enums.product.BomFinishProductEnum;
import com.xbongbong.saas.enums.product.BomMaterielProductEnum;
import com.xbongbong.saas.enums.product.ContractOutstockProductEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.enums.product.InstockProductEnum;
import com.xbongbong.saas.enums.product.InventoryProductEnum;
import com.xbongbong.saas.enums.product.OpportunityProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionInstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderFinishProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderMaterielProductEnum;
import com.xbongbong.saas.enums.product.PurchaseInstockProductEnum;
import com.xbongbong.saas.enums.product.PurchaseProductEnum;
import com.xbongbong.saas.enums.product.QuotationProductEnum;
import com.xbongbong.saas.enums.product.RefundInstockProductEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.enums.product.ReturnPurchaseProductEnum;
import com.xbongbong.saas.enums.product.ReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.enums.product.SupplierProductEnum;
import com.xbongbong.saas.enums.product.TransferProductEnum;
import lombok.Getter;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author: 汪腾伟
 * @date: Created in 2021/11/10 11:25
 * @description： (1)BI子产品字段映射（宽表字段和data里面的字段映射）
 *                (2)下面枚举中的dbFieldList和dataFieldList两个list中的顺序一定要对上，切忌顺序一定要对上!!!!!!
 *                (3)下面有空字符串代表宽表里面有，data里面没有
 *                (4)本枚举创建之初的目的是为了解决关联产品表中老数据data为null的情况！！！！！！！！！
 */
@Getter
public enum BISubProductCompareFieldEnum {
    /**
     * 合同产品
     */
    CONTRACT_PRODUCT(BIProductReformEnum.CONTRACT_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.CONTRACT_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.HISTORICAL_PRICE,
                    RelatedProductConstant.DISCOUNT,RelatedProductConstant.PRICE ,RelatedProductConstant.MEMO),
            Arrays.asList(ContractProductEnum.PRODUCT.getAttr(), ContractProductEnum.UNIT.getAttr(), ContractProductEnum.NUM.getAttr(),
                    ContractProductEnum.PRICE.getAttr(), ContractProductEnum.DISCOUNT.getAttr(), ContractProductEnum.SELLING_PRICE.getAttr(),
                    ContractProductEnum.MEMO.getAttr()),
            null,
            null,
            null),

    /**
     * 退货退款产品,退货数量宽表存的是负数，data里面存的是正数,所以这边建仓的时候需要加绝对值
     */
    REFUND_PRODUCT(BIProductReformEnum.REFUND_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.REFUND_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM,
                    RelatedProductConstant.PRICE, RelatedProductConstant.MEMO, RelatedProductConstant.INSTOCK_NUM,
                    RelatedProductConstant.EMPTY, RelatedProductConstant.EMPTY, RelatedProductConstant.EMPTY),
            Arrays.asList(RefundProductEnum.PRODUCT.getAttr(), RefundProductEnum.UNIT.getAttr(), RefundProductEnum.NUM.getAttr(),
                    RefundProductEnum.PRICE.getAttr(),  RefundProductEnum.MEMO.getAttr(), RefundProductEnum.INSTOCK_NUM.getAttr(),
                    ReturnPurchaseProductEnum.BATCH.getAttr(), ReturnPurchaseProductEnum.PRODUCE_DATE.getAttr(), ReturnPurchaseProductEnum.GUARANTEE_PERIOD.getAttr()),
            Arrays.asList(RelatedProductConstant.INSTOCK_NUM),
            Arrays.asList(RefundProductEnum.INSTOCK_NUM.getAttr()),
            Arrays.asList(ReturnPurchaseProductEnum.GUARANTEE_PERIOD.getAttr())
            ),

    /**
     * 销售机会产品
     */
    SALES_OPPORTUNITY_PRODUCT(BIProductReformEnum.SALES_OPPORTUNITY_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.SALES_OPPORTUNITY_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.HISTORICAL_PRICE, 
                    RelatedProductConstant.DISCOUNT, RelatedProductConstant.PRICE, RelatedProductConstant.MEMO),
            Arrays.asList(OpportunityProductEnum.PRODUCT.getAttr(), OpportunityProductEnum.UNIT.getAttr(), OpportunityProductEnum.NUM.getAttr(),
                    OpportunityProductEnum.PRICE.getAttr(), OpportunityProductEnum.DISCOUNT.getAttr(), OpportunityProductEnum.SELLING_PRICE.getAttr(),
                    OpportunityProductEnum.MEMO.getAttr()),
            null,
            null,
            null),

    /**
     * 报价单产品
     */
    QUOTATION_PRODUCT(BIProductReformEnum.QUOTATION_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.QUOTATION_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.HISTORICAL_PRICE, 
                    RelatedProductConstant.DISCOUNT, RelatedProductConstant.PRICE, RelatedProductConstant.MEMO),
            Arrays.asList(QuotationProductEnum.PRODUCT.getAttr(), QuotationProductEnum.UNIT.getAttr(), QuotationProductEnum.NUM.getAttr(),
                    QuotationProductEnum.PRICE.getAttr(), QuotationProductEnum.DISCOUNT.getAttr(), QuotationProductEnum.SELLING_PRICE.getAttr(),
                    QuotationProductEnum.MEMO.getAttr()),
            null,
            null,
            null),

    /**
     * 供应商产品
     */
    SUPPLIER_PRODUCT(BIProductReformEnum.SUPPLIER_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.SUPPLIER_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.UNIT),
            Arrays.asList(SupplierProductEnum.PRODUCT.getAttr(), SupplierProductEnum.UNIT.getAttr()),
            null,
            null,
            null),

    /**
     * 采购合同产品
     */
    PURCHASE_PRODUCT(BIProductReformEnum.PURCHASE_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.PURCHASE_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.PRODUCT_PRICE, 
                    RelatedProductConstant.MEMO, RelatedProductConstant.INSTOCK_NUM, RelatedProductConstant.OUTSTOCK_NUM),
            Arrays.asList(PurchaseProductEnum.PRODUCT.getAttr(), PurchaseProductEnum.UNIT.getAttr(), PurchaseProductEnum.NUM.getAttr(),
                    PurchaseProductEnum.PURCHASE_PRICE.getAttr(), PurchaseProductEnum.MEMO.getAttr(),
                    PurchaseProductEnum.INSTOCK_NUM.getAttr(), PurchaseProductEnum.RETURN_NUM.getAttr()),
            Arrays.asList(RelatedProductConstant.INSTOCK_NUM, RelatedProductConstant.OUTSTOCK_NUM),
            Arrays.asList(PurchaseProductEnum.INSTOCK_NUM.getAttr(), PurchaseProductEnum.RETURN_NUM.getAttr()),
            null),
    /**
     * 采购退货单产品
     */
    RETURNED_PURCHASE_PRODUCT(BIProductReformEnum.RETURNED_PURCHASE_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.RETURNED_PURCHASE_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.PRODUCT_PRICE, 
                    RelatedProductConstant.MEMO, RelatedProductConstant.EMPTY, RelatedProductConstant.EMPTY, RelatedProductConstant.EMPTY, RelatedProductConstant.OUTSTOCK_NUM),
            Arrays.asList(ReturnPurchaseProductEnum.PRODUCT.getAttr(), ReturnPurchaseProductEnum.UNIT.getAttr(), ReturnPurchaseProductEnum.NUM.getAttr(),
                    ReturnPurchaseProductEnum.PURCHASE_PRICE.getAttr(), ReturnPurchaseProductEnum.MEMO.getAttr(), ReturnPurchaseProductEnum.BATCH.getAttr(),
                    ReturnPurchaseProductEnum.PRODUCE_DATE.getAttr(), ReturnPurchaseProductEnum.GUARANTEE_PERIOD.getAttr(), ReturnPurchaseProductEnum.OUTSTOCK_NUM.getAttr()),
            Arrays.asList(RelatedProductConstant.OUTSTOCK_NUM),
            Arrays.asList(ReturnPurchaseProductEnum.OUTSTOCK_NUM.getAttr()),
            Arrays.asList(ReturnPurchaseProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * Bom清单成品产品
     */
    BOM_BILL_PRODUCT(BIProductReformEnum.BOM_BILL_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.BOM_BILL_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.MEMO, RelatedProductConstant.PRODUCT_UNIT),
            Arrays.asList(BomFinishProductEnum.PRODUCT.getAttr(), BomFinishProductEnum.NUM.getAttr(), BomFinishProductEnum.MEMO.getAttr(),
                    BomFinishProductEnum.UNIT.getAttr()),
            null,
            null,
            null),

    /**
     * Bom清单物料产品
     */
    BOM_BILL_MATERIEL(BIProductReformEnum.BOM_BILL_MATERIEL.getSubProductBusinessType(), BIProductReformEnum.BOM_BILL_MATERIEL.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.MEMO, RelatedProductConstant.ATTRITION_RATE, 
                    RelatedProductConstant.PRODUCT_UNIT),
            Arrays.asList(BomMaterielProductEnum.PRODUCT.getAttr(), BomMaterielProductEnum.NUM.getAttr(), BomMaterielProductEnum.MEMO.getAttr(),
                    BomMaterielProductEnum.LOSS_RATE.getAttr(), BomMaterielProductEnum.UNIT.getAttr()),
            null,
            null,
            null),

    /**
     * 生产单成品产品
     */
    PRODUCTION_ORDER_PRODUCT(BIProductReformEnum.PRODUCTION_ORDER_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.PRODUCTION_ORDER_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.MEMO),
            Arrays.asList(ProductionOrderFinishProductEnum.PRODUCT.getAttr(), ProductionOrderFinishProductEnum.UNIT.getAttr(),
                    ProductionOrderFinishProductEnum.NUM.getAttr(), ProductionOrderFinishProductEnum.MEMO.getAttr()),
            null,
            null,
            null),

    /**
     * 生产单物料产品
     */
    PRODUCTION_ORDER_MATERIEL(BIProductReformEnum.PRODUCTION_ORDER_MATERIEL.getSubProductBusinessType(), BIProductReformEnum.PRODUCTION_ORDER_MATERIEL.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.MEMO, 
                    RelatedProductConstant.ATTRITION_RATE, RelatedProductConstant.OUTSTOCK_NUM),
            Arrays.asList(ProductionOrderMaterielProductEnum.PRODUCT.getAttr(), ProductionOrderMaterielProductEnum.UNIT.getAttr(),
                    ProductionOrderMaterielProductEnum.NUM.getAttr(), ProductionOrderMaterielProductEnum.MEMO.getAttr(),
                    ProductionOrderMaterielProductEnum.LOSS_RATE.getAttr(), ProductionOrderMaterielProductEnum.OUTSTOCK_NUM.getAttr()),
            Arrays.asList(RelatedProductConstant.OUTSTOCK_NUM),
            Arrays.asList(ProductionOrderMaterielProductEnum.OUTSTOCK_NUM.getAttr()),
            null),

    /**
     * 装配出入库单-出库产品 成本小计宽表没有现成字段
     */
    ASSEMBLE_PRODUCT_OUT(BIProductReformEnum.ASSEMBLE_PRODUCT_OUT.getSubProductBusinessType(), BIProductReformEnum.ASSEMBLE_PRODUCT_OUT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, 
                    RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(AssembleProductEnum.PRODUCT.getAttr(), AssembleProductEnum.UNIT.getAttr(), AssembleProductEnum.NUM.getAttr(),
                    AssembleProductEnum.COST.getAttr(), AssembleProductEnum.MEMO.getAttr(), AssembleProductEnum.BATCH.getAttr(),
                    AssembleProductEnum.PRODUCE_DATE.getAttr(), AssembleProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(AssembleProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 装配出入库单-入库产品
     */
    ASSEMBLE_PRODUCT_IN(BIProductReformEnum.ASSEMBLE_PRODUCT_IN.getSubProductBusinessType(), BIProductReformEnum.ASSEMBLE_PRODUCT_IN.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, 
                    RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(AssembleInProductEnum.PRODUCT.getAttr(), AssembleInProductEnum.UNIT.getAttr(), AssembleInProductEnum.NUM.getAttr(),
                    AssembleInProductEnum.COST.getAttr(), AssembleInProductEnum.MEMO.getAttr(), AssembleInProductEnum.BATCH.getAttr(),
                    AssembleInProductEnum.PRODUCE_DATE.getAttr(), AssembleInProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(AssembleInProductEnum.GUARANTEE_PERIOD.getAttr())),
    /**
     * 盘点单-盘点产品
     */
    INVENTORY_PRODUCT(BIProductReformEnum.INVENTORY_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.INVENTORY_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM,
                    RelatedProductConstant.ORI_NUM,RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE,
                    RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(InventoryProductEnum.PRODUCT.getAttr(), InventoryProductEnum.UNIT.getAttr(), InventoryProductEnum.NUM.getAttr(),
                    InventoryProductEnum.STOCK.getAttr(),InventoryProductEnum.MEMO.getAttr(), InventoryProductEnum.BATCH.getAttr(),
                    InventoryProductEnum.PRODUCE_DATE.getAttr(), InventoryProductEnum.GUARANTEE_PERIOD.getAttr()),
            Arrays.asList(RelatedProductConstant.ORI_NUM),
            Arrays.asList(InventoryProductEnum.STOCK.getAttr()),
            Arrays.asList(InventoryProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 调拨单-调拨产品
     */
    TRANSFER_PRODUCT(BIProductReformEnum.TRANSFER_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.TRANSFER_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM,
                    RelatedProductConstant.INSTOCK_NUM, RelatedProductConstant.MEMO,
                    RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(TransferProductEnum.PRODUCT.getAttr(), TransferProductEnum.UNIT.getAttr(), TransferProductEnum.NUM.getAttr(),
                    TransferProductEnum.INSTOCK_NUM.getAttr(), TransferProductEnum.MEMO.getAttr(), TransferProductEnum.BATCH.getAttr(),
                    TransferProductEnum.PRODUCE_DATE.getAttr(), TransferProductEnum.GUARANTEE_PERIOD.getAttr()),
            Arrays.asList(RelatedProductConstant.INSTOCK_NUM),
            Arrays.asList(TransferProductEnum.INSTOCK_NUM.getAttr()),
            Arrays.asList(TransferProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 采购入库单-入库产品
     */
    PURCHASE_INSTOCK_PRODUCT(BIProductReformEnum.PURCHASE_INSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.PURCHASE_INSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST,
                    RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(PurchaseInstockProductEnum.PRODUCT.getAttr(),PurchaseInstockProductEnum.UNIT.getAttr(), PurchaseInstockProductEnum.NUM.getAttr(),
                    PurchaseInstockProductEnum.COST.getAttr(), PurchaseInstockProductEnum.MEMO.getAttr(), PurchaseInstockProductEnum.BATCH.getAttr(),
                    PurchaseInstockProductEnum.PRODUCE_DATE.getAttr(), PurchaseInstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(PurchaseInstockProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 销售退货入库单-入库产品
     */
    REFUND_INSTOCK_PRODUCT(BIProductReformEnum.REFUND_INSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.REFUND_INSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.PRICE, 
                    RelatedProductConstant.COST, RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE,
                    RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(RefundInstockProductEnum.PRODUCT.getAttr(), RefundInstockProductEnum.UNIT.getAttr(), RefundInstockProductEnum.NUM.getAttr(),
                    RefundInstockProductEnum.PRICE.getAttr(), RefundInstockProductEnum.COST.getAttr(), RefundInstockProductEnum.MEMO.getAttr(),
                    RefundInstockProductEnum.BATCH.getAttr(), RefundInstockProductEnum.PRODUCE_DATE.getAttr(), PurchaseInstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            //脏数据兼容：测试环境有部分数据宽表有值，data内没有，因此做一层处理
            Arrays.asList(RelatedProductConstant.PRICE),
            Arrays.asList(RefundInstockProductEnum.PRICE.getAttr()),
            Arrays.asList(PurchaseInstockProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 其他入库单 - 盘盈入库、调拨入库、装配入库也归属该类-入库产品
     */
    OTHER_INSTOCK_PRODUCT(BIProductReformEnum.OTHER_INSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.OTHER_INSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, 
                    RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(InstockProductEnum.PRODUCT.getAttr(), InstockProductEnum.UNIT.getAttr(), InstockProductEnum.NUM.getAttr(),
                    InstockProductEnum.COST.getAttr(), InstockProductEnum.MEMO.getAttr(), InstockProductEnum.BATCH.getAttr(),
                    InstockProductEnum.PRODUCE_DATE.getAttr(), InstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(InstockProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 生产入库单 - 入库产品
     */
    PRODUCTION_INSTOCK_PRODUCT(BIProductReformEnum.PRODUCTION_INSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.PRODUCTION_INSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, 
                    RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(ProductionInstockProductEnum.PRODUCT.getAttr(), ProductionInstockProductEnum.UNIT.getAttr(), ProductionInstockProductEnum.NUM.getAttr(),
                    ProductionInstockProductEnum.COST.getAttr(),ProductionInstockProductEnum.MEMO.getAttr(),
                    ProductionInstockProductEnum.BATCH.getAttr(), ProductionInstockProductEnum.PRODUCE_DATE.getAttr(), ProductionInstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(ProductionInstockProductEnum.GUARANTEE_PERIOD.getAttr())),
    /**
     * 生产退料单- 入库产品
     */
    RETURNED_MATERIEL_INSTOCK_PRODUCT(BIProductReformEnum.RETURNED_MATERIEL_INSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.RETURNED_MATERIEL_INSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM,
                    RelatedProductConstant.COST,  RelatedProductConstant.MEMO,
                    RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(ReturnedMaterielInstockProductEnum.PRODUCT.getAttr(), ReturnedMaterielInstockProductEnum.UNIT.getAttr(), ReturnedMaterielInstockProductEnum.NUM.getAttr(),
                    ReturnedMaterielInstockProductEnum.COST.getAttr(), ReturnedMaterielInstockProductEnum.MEMO.getAttr(),
                    ReturnedMaterielInstockProductEnum.BATCH.getAttr(), ReturnedMaterielInstockProductEnum.PRODUCE_DATE.getAttr(),
                    ReturnedMaterielInstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(ReturnedMaterielInstockProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 销售出库单- 出库产品
     */
    CONTRACT_OUTSTOCK_PRODUCT(BIProductReformEnum.CONTRACT_OUTSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.CONTRACT_OUTSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.PRODUCT_PRICE,
                    RelatedProductConstant.COST,  RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE,
                    RelatedProductConstant.GUARANTEE_PERIOD,RelatedProductConstant.DISCOUNT),
            Arrays.asList(ContractOutstockProductEnum.PRODUCT.getAttr(), ContractOutstockProductEnum.UNIT.getAttr(), ContractOutstockProductEnum.NUM.getAttr(),
                    ContractOutstockProductEnum.SELLING_PRICE.getAttr(), ContractOutstockProductEnum.COST.getAttr(), ContractOutstockProductEnum.MEMO.getAttr(),
                    ContractOutstockProductEnum.BATCH.getAttr(), ContractOutstockProductEnum.PRODUCE_DATE.getAttr(), ContractOutstockProductEnum.GUARANTEE_PERIOD.getAttr(),
                    ContractOutstockProductEnum.DISCOUNT.getAttr()),
            null,
            null,
            Arrays.asList(ContractOutstockProductEnum.GUARANTEE_PERIOD.getAttr())),
    /**
     * 采购退货出库单- 出库产品
     */
    RETURNED_PURCHASE_OUTSTOCK_PRODUCT(BIProductReformEnum.RETURNED_PURCHASE_OUTSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.RETURNED_PURCHASE_OUTSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, RelatedProductConstant.MEMO,
                    RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(ReturnedPurchaseOutstockProductEnum.PRODUCT.getAttr(), ReturnedPurchaseOutstockProductEnum.UNIT.getAttr(), ReturnedPurchaseOutstockProductEnum.NUM.getAttr(),
                    ReturnedPurchaseOutstockProductEnum.COST.getAttr(), ReturnedPurchaseOutstockProductEnum.MEMO.getAttr(),
                    ReturnedPurchaseOutstockProductEnum.BATCH.getAttr(), ReturnedPurchaseOutstockProductEnum.PRODUCE_DATE.getAttr(), ReturnedPurchaseOutstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(ReturnedPurchaseOutstockProductEnum.GUARANTEE_PERIOD.getAttr())),

    /**
     * 其他出库单 - 盘亏出库、调拨出库、装配出库也归属该类- 出库产品
     */
    OTHER_OUTSTOCK_PRODUCT(BIProductReformEnum.OTHER_OUTSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.OTHER_OUTSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, RelatedProductConstant.MEMO,
                    RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(OutstockProductEnum.PRODUCT.getAttr(), OutstockProductEnum.UNIT.getAttr(), OutstockProductEnum.NUM.getAttr(),
                    OutstockProductEnum.COST.getAttr(), OutstockProductEnum.MEMO.getAttr(),
                    OutstockProductEnum.BATCH.getAttr(), OutstockProductEnum.PRODUCE_DATE.getAttr(), OutstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(OutstockProductEnum.GUARANTEE_PERIOD.getAttr())),
    /**
     * 生产领料单 - 出库产品
     */
    PRODUCTION_MATERIEL_OUTSTOCK_PRODUCT(BIProductReformEnum.PRODUCTION_MATERIEL_OUTSTOCK_PRODUCT.getSubProductBusinessType(), BIProductReformEnum.PRODUCTION_MATERIEL_OUTSTOCK_PRODUCT.getType(),
            Arrays.asList(RelatedProductConstant.PRODUCT_ID, RelatedProductConstant.PRODUCT_UNIT, RelatedProductConstant.PRODUCT_NUM, RelatedProductConstant.COST, 
                     RelatedProductConstant.MEMO, RelatedProductConstant.BATCH, RelatedProductConstant.PRODUCE_DATE, RelatedProductConstant.GUARANTEE_PERIOD),
            Arrays.asList(ProductionMaterielOutstockProductEnum.PRODUCT.getAttr(), ProductionMaterielOutstockProductEnum.UNIT.getAttr(), ProductionMaterielOutstockProductEnum.NUM.getAttr(),
                    ProductionMaterielOutstockProductEnum.COST.getAttr(), ProductionMaterielOutstockProductEnum.MEMO.getAttr(),
                    ProductionMaterielOutstockProductEnum.BATCH.getAttr(), ProductionMaterielOutstockProductEnum.PRODUCE_DATE.getAttr(),
                    ProductionMaterielOutstockProductEnum.GUARANTEE_PERIOD.getAttr()),
            null,
            null,
            Arrays.asList(ProductionMaterielOutstockProductEnum.GUARANTEE_PERIOD.getAttr())),
    ;

    /**
     * 产品子表单业务类型
     */
    private Integer subProductBusinessType;

    /**
     * 增加一个字段用于区分产品，比如bom单中有成品产品和物料产品，得有标识去区分，
     * 值最好要用各自产品表中的type字段，比如tb_saas_bom_product中有type去区分成品和物料
     */
    private Integer type;

    /**
     *  数据库宽表字段列表
     */
    private List<String> dbFieldList;

    /**
     * 数据库data里面的字段列表
     */
    private List<String> dataFieldList;

    /**
     * 主要是为了处理数据库宽表存了，但是data内没有存，整理的数据库字段
     * 宽表字段
     */
    private List<String> limitDbFieldList;

    /**
     * 主要是为了处理数据库宽表存了，但是data内没有存，整理的data里面的字段
     * 宽表需在data内映射的字段（实际又没有把值塞入data内）
     */
    private List<String> limitDataFieldList;

    /**
     * 存储时间字段并且需要转化成天数的attr列表
     */
    private List<String> dateTimeAttrList;

    BISubProductCompareFieldEnum(Integer subProductBusinessType, Integer type, List<String> dbFieldList, List<String> dataFieldList,
                                 List<String> limitDbFieldList, List<String> limitDataFieldList, List<String> dateTimeAttrList) {
        this.subProductBusinessType = subProductBusinessType;
        this.type = type;
        this.dbFieldList = dbFieldList;
        this.dataFieldList = dataFieldList;
        this.limitDbFieldList = limitDbFieldList;
        this.limitDataFieldList = limitDataFieldList;
        this.dateTimeAttrList = dateTimeAttrList;
    }

    /**
     * 根据产品子表单业务类型和type获取每个产品子表单的宽表与data里面的字段进行映射
     *
     * @param subProductBusinessType 产品子表单的businessType
     * @param type 类型
     * @return
     */
    public static Map<String, String> getMappingFieldMap(Integer subProductBusinessType, Integer type) {
        Map<String, String> fieldMap = new HashMap<>();
        for (BISubProductCompareFieldEnum biSubProductCompareFieldEnum : BISubProductCompareFieldEnum.values()) {
            if (Objects.equals(subProductBusinessType, biSubProductCompareFieldEnum.getSubProductBusinessType())
                    && Objects.equals(type, biSubProductCompareFieldEnum.getType())) {
                List<String> dbFieldList = biSubProductCompareFieldEnum.getDbFieldList();
                List<String> dataFieldList = biSubProductCompareFieldEnum.getDataFieldList();
                for (int i = 0; i < dataFieldList.size(); i++) {
                    fieldMap.put(dataFieldList.get(i), dbFieldList.get(i));
                }
                return fieldMap;
            }
        }
        return fieldMap;
    }

    /**
     * 主要是为了处理数据库字段存在，但是data里面字段不存在
     *
     * @param subProductBusinessType 产品子表单的businessType
     * @param type 类型
     * @return
     */
    public static Map<String, String> getDbFieldExistHandleMap(Integer subProductBusinessType, Integer type) {
        Map<String, String> fieldMap = new HashMap<>();
        for (BISubProductCompareFieldEnum biSubProductCompareFieldEnum : BISubProductCompareFieldEnum.values()) {
            if (Objects.equals(subProductBusinessType, biSubProductCompareFieldEnum.getSubProductBusinessType())
                    && Objects.equals(type, biSubProductCompareFieldEnum.getType())) {
                List<String> limitDbFieldList = biSubProductCompareFieldEnum.getLimitDbFieldList();
                List<String> limitDataFieldList = biSubProductCompareFieldEnum.getLimitDataFieldList();
                if (!CollectionUtils.isEmpty(limitDbFieldList) && !CollectionUtils.isEmpty(limitDataFieldList)) {
                    for (int i = 0; i < limitDbFieldList.size(); i++) {
                        fieldMap.put(limitDbFieldList.get(i), limitDataFieldList.get(i));
                    }
                }
                return fieldMap;
            }
        }
        return fieldMap;
    }

    /**
     * 根据产品子表的业务类型和类型去获取有哪些需要处理的时间字段
     *
     * @param subProductBusinessType 产品子表单的businessType
     * @param type 类型
     * @return
     */
    public static List<String> getDateTimeList(Integer subProductBusinessType, Integer type) {
        for (BISubProductCompareFieldEnum biSubProductCompareFieldEnum : BISubProductCompareFieldEnum.values()) {
            if (Objects.equals(subProductBusinessType, biSubProductCompareFieldEnum.getSubProductBusinessType())
                    && Objects.equals(type, biSubProductCompareFieldEnum.getType())) {
                return biSubProductCompareFieldEnum.getDateTimeAttrList();
            }
        }
        return null;
    }
}
